var initCxt = undefined;
var datasets = [];
var initUtil = undefined ;

var Field = function(id, name, dataset, regex, value, datatype,
		binding,dateformat) {
	this.id = id;
	this.name = name;
	this.dataset = dataset;
	this.regex = regex;
	this.value = value;
	this.dataType = datatype;
	this.binding = binding;
	this.dateformat = dateformat ;
};

Field.prototype = {
	getValue : function() {
		return this.value;
	},
	getDataset : function() {
		return this.dataset;
	},
	getDatatype : function() {
		return this.dataType;
	},
	setBinding : function(binding) {
		this.binding = binding;
	}
};

var Grid = function (id,pageSize,pageNo,type){
	this.id = id ;
	this.pageSize = pageSize ;
	this.pageNo = pageNo ;
	this.type = type ;
	this.arrField = undefined ;
	this.records = undefined ;
	this.curEditIndex =  undefined ;
};

var Record = function(rowData){
	this.rowData = rowData ;
};

Grid.prototype = {
		setCurEditIndex:function(value){
			this.curEditIndex = value ;
		},
		addField : function(field){
			if (this.arrField==undefined) {
				this.arrField = [];
			} 
			this.arrField[this.arrField.length] = field;
		},
		getField:function(key){
			var field = undefined ;
			if(this.arrField){
				for(var i=0 ,len=this.arrField.length ; i<len ; i++){
					if(this.arrField[i].id==key || this.arrField[i].name == key){
						field = this.arrField[i] ;
					}
				}
			}
			return field ;
		},
		getCurrentRecord : function(){
			var tmpRcd = undefined ;
			if(this.type=="datagrid"){
				tmpRcd = this.records[this.curEditIndex] ;
			}else if(this.type=="treegrid"){
				for(var i=0,len=this.records.length;i<len;i++ ){
					if(this.records[i] && this.records[i].rowData.id==this.curEditIndex){
						tmpRcd = this.records[i] ;
						break ;
					}
				}
			}
			return tmpRcd ;
		},
		addRecord : function(record){
			if(this.records == undefined){
				this.records = [] ;
			}
			this.records[this.records.length] = record ;
		},
		removeRecord:function(rcdId){
			for(var i=0,len=this.records.length;i<len;i++ ){
				if(this.records[i] && this.records[i].rowData.id==rcdId){
					if(this.records[i].rowData.rowStatus=INSERT){
						delete this.records[i] ;
					}else{
						this.records[i].rowData.rowStatus=DELETE ;
					}
					this.curEditIndex=undefined ;
				}
			}
		}
};

var Dataset = function(name, fields, grids,curEditGridId) {
	this.name = name;
	this.fields = fields;
	this.grids = grids;
	this.curEditGridId = curEditGridId ;
};
Dataset.prototype = {
	getField : function(key) {
		var tmpFld = {};
		var arrFld = this.fields;
		for ( var i = 0, len = arrFld.length; i < len; i++) {
			if (arrFld[i].id == key || fields[i].name == key) {
				tmpFld = arrFld[i];
				break;
			}
		}
		return tmpFld;
	},
	
	setValue : function(key, value) {
		var arrFld = this.fields;
		for ( var i = 0, len = arrFld.length; i < len; i++) {
			if (arrFld[i].id == key || arrFld[i].name == key) {
				var tmpFld = arrFld[i];
				tmpFld["value"] = value;
				break;
			}
		}
	},
	addField : function(field) {
		if (this.fields) {
			this.fields[this.fields.length] = field;
		} else {
			this.fields = [];
			this.fields[0] = field;
		}
	},
	addGrid:function(grid){
		if (this.grids) {
			this.grids[this.grids.length] = grid;
		} else {
			this.grids = [];
			this.grids[0] = grid;
		}
	}
};


jQuery.extend({
	ds : function(key) {
		var ds = null;
		for ( var i = 0, length = datasets.length; i < length; i++) {
			if (datasets[i].name == key) {
				ds = datasets[i];
				break;
			}
		}
		return ds;
	},
	grid : function(dskey,gridkey){
		var grids =  this.ds(dskey).grids;
		var tmp = undefined ;
		for ( var i = 0, length =grids.length; i < length; i++) {
			if (grids[i].id == gridkey) {
				tmp = grids[i];
				break;
			}
		}
		return tmp;
	}
});

var InitUtil = function(jsonObj) {
	this.jsonObj = jsonObj;
};

InitUtil.prototype = {
	initDatasets : function() {
		// beforeInit();
		var tmpDst = this.jsonObj.datasets ;
		var len = tmpDst.length;
		for ( var i = 0; i < len; i++) {
			var tmp = tmpDst[i];
			datasets[i] = new Dataset(tmp.name);
			this.initFields(tmp, datasets[i]);
			// initRecord(tmp,datasets[tmp.name]) ;
			this.initGrids(tmp, datasets[i]) ;
		}
		this.initBindings();
		// afterInit();
	},
	initGrids : function(srcDataset, tagetDataset) {
		var arrGrid = srcDataset.grids;
		for ( var i = 0, len = arrGrid.length; i < len; i++) {
			var grid = new Grid(arrGrid[i].id,arrGrid[i].pageSize,arrGrid[i].pageNo,arrGrid[i].type);
			tagetDataset.addGrid(grid) ;
			var arrFld = arrGrid[i].fields ;
			for (var j = 0 ,size=arrFld.length ; j<size ; j++){
				var field = new Field(arrFld[j].id, arrFld[j].name,
						arrFld[j].dataset, arrFld[j].regex,
						arrFld[j].value, arrFld[j].datatype,
						arrFld[j].binding,arrFld[j].dateformat );
				grid.addField(field) ;
			}
			
		}
	},
	initFields: function(srcDataset, tagetDataset) {
		var arrFld = srcDataset.fields;
		for ( var i = 0, len = arrFld.length; i < len; i++) {
			var field = new Field(arrFld[i].id, arrFld[i].name,
					arrFld[i].dataset, arrFld[i].regex,
					arrFld[i].value, arrFld[i].datatype,
					arrFld[i].binding,arrFld[i].dateformat );
			tagetDataset.addField(field);
		}
	},
	initBindings : function() {
		var bindings = jQuery("[dataset]");
		jQuery.each(bindings, function(index, binding) {
			var type = binding.getAttribute("type");
			if (type == "text" || type=="password" || type =="textarea") {
				jQuery(binding).change(
					function() {
						jQuery.ds(this.getAttribute("dataset")).setValue(
								this.getAttribute("id"), this.value);
					});
			} else if("validatebox"==type){
				$(this).validatebox({onChange:function(newVal,oldVal){
					$.message.alert(newVal) ;
				}});
			} else if (type == "datebox") {
				$("#" + binding.id).datebox({
							onSelect : function(date) {
								var tmp = date.getFullYear() + "-"
										+ (date.getMonth() + 1) + "-"
										+ date.getDate();
								jQuery.ds(this.getAttribute("dataset")).setValue(
										this.getAttribute("id"), tmp);
							}
						});
			} else if (type == "datetime") {
				$("#" + binding.id).datetimebox({
					onSelect : function(date) {
						var tmp = date.getFullYear() + "-"
								+ (date.getMonth() + 1) + "-"
								+ date.getDate();
						jQuery.ds(this.getAttribute("dataset")).setValue(
								this.getAttribute("id"), tmp);
					}
				});
			}else if (type == "combobox") {
				$("#" + binding.id).combobox({
					onSelect : function(record) {
						var value = record.id ;
						jQuery.ds(this.getAttribute("dataset")).setValue(
								this.getAttribute("id"), value);
					}
				});
			}else if (type == "numberbox") {
				$("#" + binding.id).numberbox({
					onChange : function(newVal,oldVal) {
						jQuery.ds(this.getAttribute("dataset")).setValue(
								this.getAttribute("id"), newVal);
					}
				});
			}else if (type == "searchbox") {
				$("#" + binding.id).searchbox({
					searcher : function(name,value) {
						alert(name+value) ;
					}
				});
				
				$("#" + binding.id).searchbox("options").search ;
			}else if (type == "pagination") {
				$("#" + binding.id).pagination({
				});
			}else if(type == "datagrid"){
				var datagrid = $("#"+binding.id);
				datagrid .datagrid({onClickRow:function(rowIndex, rowData){
					 var gridBinding=$(this) ;
					 onGridClickAction(rowData,gridBinding,rowIndex);
					 	
				 	},onRowContextMenu:function(e, rowIndex, rowData){
				 		var menu = $("#v_menu") ;
						if(menu.length==0){
					 		$(this).after("<div id=\"v_menu\"  data-options=\"onClick:menuHandler\" style=\"width:150px;\"><div data-options=\"name:'append'\">添加子元素</div><div data-options=\"name:'edit'\">编辑</div><div data-options=\"name:'cut'\">剪切</div><div data-options=\"name:'copy'\">复制</div><div data-options=\"name:'paste'\">粘贴</div></div>") ;
							menu = $("#v_menu")
							menu.menu({});
						}
				 		e.preventDefault();
				 		//$(this).treegrid('select', rowIndex);
				 		menu.menu('show', {
				 			left : e.pageX,
				 			top : e.pageY
				 		});
				 	},onDblClickRow:function(rowIndex,rowData){
				 		var gridBinding=$(this) ;
					 	onGridClickAction(rowData,gridBinding,rowIndex);
				 	}
				});
				
				
			}else if(type=="treegrid"){
				var tg= $("#" + binding.id) ;
				tg.treegrid({onContextMenu:function(e,rowData){
						var menu = $("#v_menu") ;
						var binding = $(this) ;
						if(menu.length==0){
							binding.after("<div id=\"v_menu\"  data-options=\"onClick:menuHandler\" style=\"width:150px;\"><div data-options=\"name:'append'\">添加子元素</div><div data-options=\"name:'edit'\">编辑</div><div data-options=\"name:'cut'\">剪切</div><div data-options=\"name:'copy'\">复制</div><div data-options=\"name:'paste'\">粘贴</div></div>") ;
							menu = $("#v_menu")
							menu.menu({});
						}
						e.preventDefault();
						var tg = jQuery.grid(binding.attr("dataset"),binding.attr("id"))
						//if(tg.curEditIndex!=undefined){
				 		accept(binding,rowData["id"]) ;
				 		//}
				 		//if(tg.curEditIndex!=undefined){
			 			menu.menu("options").dataset=binding.attr("dataset");
				 		tg.curEditIndex=rowData["id"] ;
				 		menu.menu('show', {
				 			left : e.pageX,
				 			top : e.pageY
				 		});
				 		//}
				 		binding.treegrid("select",tg.curEditIndex);
				 	},onClickRow:function(row){
				 		var binding = $(this) ;
				 		onGridClickAction(row,binding,row["id"]) ;
				 	}
				});
			}else if(type=="propertygrid"){
				var binding = $(this) ;
				binding.propertygrid({
					onClickRow:function(index,rowData){
					var arrEditor = $(this).propertygrid("getEditors",index) ;
					jQuery.each(arrEditor,function(index,editor){
						bindListener(editor,rowData) ;
					})}	
				});
			}
		});
	}
} ;

function onGridClickAction(rowData,gridBinding,rowIndex){
	//beforeGridClickAction(gridBinding,rowIndex);
	var tmpgrid = jQuery.grid(gridBinding.attr("dataset"),gridBinding.attr("id")) ;
	
	var type=gridBinding.attr("type");
	if(type=="datagrid"){
		 	if(tmpgrid.curEditIndex!=undefined){
		 		if( !gridBinding.datagrid("validateRow",tmpgrid.curEditIndex)&& rowIndex!=tmpgrid.curEditIndex){
			 		rowIndex=tmpgrid.curEditIndex ;
			 		$.messager.alert("warning","请正确输入正在编辑的行或者废弃正在编辑的行","warning");
			 	}else{
			 		accept(gridBinding,rowIndex);
			 	}
		 	}
		 	tmpgrid.setCurEditIndex(rowIndex) ;
		 	gridBinding.datagrid("selectRow",rowIndex) ;
	}else if(type=="treegrid"){
 		if(tmpgrid.curEditIndex!=undefined){
 			accept(gridBinding,rowIndex) ;
 		}
 		//if(tmpgrid.curEditIndex==undefined){
	 	tmpgrid.curEditIndex=rowIndex ;
 		//}
 		gridBinding.treegrid("select",tmpgrid.curEditIndex);
	}
	

	jQuery.each(arrEditor,function(index,editor){
		bindListener(editor,rowData);
	}) ;
	grid.curEditIndex = rowIndex ;
	

}


function bindListener(editor,rowData){
	var type = editor.type ;
	var target = $(editor.target) ;
	var field = editor.field ;
	if(type=="combobox"){
		var options = target.combobox("options") ;
		options.onSelect=function(record){
			setRecordValue(field,record.value,rowData);
			loadCtrlData(editor.field,record.value,rowData) ;
		} ;
		options.value=rowData[field] ;
		if(rowData['name']=="buttons"){
			target.combobox("loadData",buttons1);
		}
	}else if(type=="datebox"){
		
		var options = target.datebox("options") ;
		options.onSelect=function(date){
						var tmpVal = date.getFullYear() + "-"
						+ (date.getMonth() + 1) + "-"
						+ date.getDate();
		setRecordValue(field,tmpVal,rowData);
		} ;
	}else if(type=="validatebox"){
		target.validatebox("onBlur",function(val){
			setRecordValue(field,val,rowData);
		});
	}else if(type=="numberbox"){
		var options = target.numberbox("options") ;
		options.onChange=function(newVal,oldVal){
			setRecordValue(field,newVal,rowData);
		};
	}
}

function setRecordValue(field,newVal,rowData){
	//alert(rowData[field]+"--"+newVal)
	if(rowData[field]!=newVal){
		//010 表示数据已经被更改	
		rowData['rowState']='010' ;
	}
	rowData[field] = newVal ;
}
/********************************contextmenu action start**************************/
function menuHandler(item){
	var binding = $(this) ;
	switch (item.name) {
		case "cut":
			 // statements
		break;
		case "append":
			 append(binding);
		break;
		case "edit":
			 editgrid(binding);
		break;
		case "copy":
			 // statements
		break;
		case "paste":
			 // statements
		break;
		default:
			$.messager.alert(item.text,"not find action...") ;
	}
}


/********************************contextmenu action end****************************/

/*********************datagrid operation start ***************************/

function getGridid(param){
	var binding = param.closest("div") ;
	var curgridid = binding.attr("grid") ;
	gridid=curgridid ;
	jQuery.ds(binding.attr("dataset")).curEditGridId=curgridid ;
	return gridid ;
}

function getGridBinding(param){
	var binding = param.closest("div") ;
	var curgridid = binding.attr("grid") ;
	gridid=curgridid ;
	jQuery.ds(binding.attr("dataset")).curEditGridId=curgridid ;
	return $("#"+gridid) ;
}

function getCurrentRow(gridid){
	var binding=$("#"+gridid) ;
	var row = binding.datagrid("getSelected") ;
	return row ;
}


function remove(binding){
	//var binding=$("#"+gridid) ;
	var type = binding.attr("type");
	var row = binding.datagrid("getSelected") ;
	if(row==undefined){
		$.messager.alert("warning","请先选择要删除的记录");
	}else{
		if(type=="datagrid"){
			binding.datagrid("deleteRow",binding.datagrid("getRowIndex",row));
		}else if(type=="treegrid"){
			binding.treegrid("remove",row["id"]);
		}
		
		//jQuery.grid(binding.attr("dataset"),gridid).curEditIndex=undefined ;
		//同步到dataset ，将dataset中相应grid对应的记录标记为已删除　rowstate=011 ;
		var grid = jQuery.grid(binding.attr("dataset"),gridid);
		grid.removeRecord(type=="datagrid"?binding.datagrid("getRowIndex",row):row["id"]) ;
	}
}

function validateGrid(type,binding,id){
	var flag = false ;
	if(type=="datagrid"){
		flag = binding.datagrid("validateRow",id);
	}else if(type=="treegrid"){
		flag = binding.treegrid("validateRow",id);
	}
	return flag ;
}

function accept(binding,newId){
	//var binding = $("#"+gridid) ;
	var type = binding.attr("type");
	var grid = jQuery.grid(binding.attr("dataset"),binding.attr("id")) ;
	var id = grid.curEditIndex ;
	if(newId==undefined && id==undefined ){
		$.messager.alert("warning","没有选择编辑行","warning") ;
		return ;
	}
	if(!validateGrid(type,binding,id)){
		$.messager.alert("warning","请正确输入当前编辑行!","warning") ;
		return ;
	}
	if(type=="datagrid"){
		binding.datagrid("acceptChanges");
		binding.datagrid("endEdit",id);
		//binding.datagrid("unselectRow",id);
	}else if(type=="treegrid"){
		fireChangeAction(grid,binding,newId);
		binding.treegrid("acceptChanges");
		binding.treegrid("endEdit",id);
		//binding.treegrid("unselect",id);
	}
	//grid.curEditIndex=undefined ;
}

function reject(binding){
	//var binding = $("#"+gridid) ;
	var type = binding.attr("type");
	var grid = jQuery.grid(binding.attr("dataset"),binding.attr("id")) ;
	var id = grid.curEditIndex ;
	if(type=="datagrid"){
		binding.datagrid("rejectChanges");
		binding.datagrid("unselectRow",id);
	}else if(type=="treegrid"){
		binding.treegrid("cancelEdit",id);
		binding.treegrid("unselect",id);
	}
	jQuery.grid(binding.attr("dataset"),gridid).curEditIndex=undefined ;
}


function insert(binding) {
	//var binding = $('#'+gridid) ;
	var type = binding.attr("type");
	var data={id:getUUID()} ;
	if(type=="datagrid"){
		binding.datagrid('appendRow',data);
	}else if(type=="treegrid"){
		binding.treegrid("append",{data:[data]});
	}
	var record = new Record(data);
	var grid = jQuery.grid(binding.attr("dataset"),gridid);
	grid.addRecord(record);
}

function editgrid(binding){
	var dsid = binding.menu("options").dataset ;
	var ds = jQuery.ds(dsid) ;
	var gridData = jQuery.grid(dsid,ds.curEditGridId) ;
	var treegrid = $("#"+ds.curEditGridId) ;
	treegrid.treegrid("select",gridData.curEditIndex).treegrid("beginEdit",gridData.curEditIndex);
	var editors = treegrid.treegrid("getEditors",gridData.curEditIndex);

	var rowData = gridData.getCurrentRecord().rowData ;
	
	jQuery.each(editors,function(index,editor){
		bindListener(editor,rowData);
		//var target = $(editor.target) ;
		initCtrl(editor,rowData,treegrid) ;
	}) ;
	
	
}

function append(binding){
	var dsid = binding.menu("options").dataset ;
	var ds = jQuery.ds(dsid) ;
	var gridData = jQuery.grid(dsid,ds.curEditGridId) ;
	var treegrid = $("#"+ds.curEditGridId) ;
	var tmpdata = {id:getUUID()};
	var curRcd = gridData.getCurrentRecord() ;
	treegrid.treegrid("append",{
		parent:curRcd.rowData.id,
		data:[tmpdata]
	});
	gridData.addRecord(new Record(tmpdata));
}
/**************************datagrid operation end ************************/

function getUUID(){
	return new UUID().id ;
}